//
//  NSString+Additions.m
//  HSKCommon
//
//  Created by Carl on 2016/11/23.
//  Copyright © 2016年 Carl. All rights reserved.
//

#import "NSString+Additions.h"
#import <CommonCrypto/CommonDigest.h>
#import <CommonCrypto/CommonCryptor.h>

@implementation NSString (Additions)

+ (BOOL)stringNilOrEmpty:(NSString *)string;
{
    NSString *str = string;
    if (str == nil) {
        return YES;
    }
    if (str == NULL) {
        return YES;
    }
    if ([str isKindOfClass:NSNull.class]) {
        return YES;
    }
    if ([str isKindOfClass:NSString.class]) {
        if (str.length == 0) {
            return YES;
        }
    }
    return NO;
}

- (NSString *)trim{
    return [self stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}

@end

@implementation NSString (Code)

- (NSString *)md5
{
    NSData *data = [self dataUsingEncoding:NSUTF8StringEncoding];
    unsigned char result[CC_MD5_DIGEST_LENGTH];
    CC_MD5([data bytes], (CC_LONG)[data length], result);
    
    NSMutableString *md5String = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH];
    for (int i=0; i<CC_MD5_DIGEST_LENGTH; i++) {
        [md5String appendFormat:@"%02X",result[i]];
    }
    return md5String;
}

- (NSString *)urlEncode
{
    return (NSString*)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,
                                                                                (CFStringRef)self,
                                                                                NULL,
                                                                                CFSTR(":/?#[]@!$’()&=*+,;"),
                                                                                kCFStringEncodingUTF8));
}

- (NSString *)urlDecode
{
    return (NSString *)CFBridgingRelease(CFURLCreateStringByReplacingPercentEscapesUsingEncoding(kCFAllocatorDefault,
                                                                                                 (CFStringRef)self,
                                                                                                 CFSTR(""),
                                                                                                 kCFStringEncodingUTF8));
}

/**
 判断原字符串是否进行过urlEncode，已进行urlEncode的直接返回self，否则进行[self stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]]编码后返回；

 @return 保证仅进行一次urlEncode的字符串
 */
- (NSString *)aUrlEncode {
	NSString *tempUrlStr = [self stringByRemovingPercentEncoding];
	if ([tempUrlStr isEqualToString:self]) {
		return [self stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
	}
	else{
		return [self copy];
	}
}

@end

@implementation NSString (Size)

- (CGSize)sizeWithFont:(UIFont *)font boundWidth:(CGFloat)width {
    return ([self sizeWithFont:font boundWidth:width lineBreak:NSLineBreakByCharWrapping]);
}

- (CGSize)sizeWithFont:(UIFont *)font boundWidth:(CGFloat)width lineBreak:(NSInteger)lineBreak {
    return ([self sizeWithFont:font boundSize:CGSizeMake(width, CGFLOAT_MAX) lineBreak:lineBreak]);
}

- (CGSize)sizeWithFont:(UIFont *)font boundSize:(CGSize)size {
    return ([self sizeWithFont:font boundSize:size lineBreak:NSLineBreakByCharWrapping]);
}

- (CGSize)sizeWithFont:(UIFont *)font boundSize:(CGSize)size lineBreak:(NSInteger)lineBreak {
    NSDictionary *attributesDict = nil;
    if (font) {
        attributesDict = @{NSFontAttributeName : font};
    }
    return ([self boundingRectWithSize:size
                               options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading
                            attributes:attributesDict
                               context:nil].size);
}

@end

@implementation NSString (Format)

- (NSString *)chinesePhoneticLetter
{
	if ([self length]) {
		NSMutableString *ms = [[NSMutableString alloc] initWithString:self];

		//先转换为带声调的拼音
		if (CFStringTransform((__bridge CFMutableStringRef)ms, 0, kCFStringTransformMandarinLatin, NO)) {
		}

		//再转换为不带声调的拼音
		if (CFStringTransform((__bridge CFMutableStringRef)ms, 0, kCFStringTransformStripDiacritics, NO)) {
		}

		//转化为大写拼音
		return [ms uppercaseString];
	}
	return self;
}

- (NSString*)formatPhoneNumberStringWithSeparator:(NSString *)separator;
{
	if ([self isValidPhoneNumber]) {
		NSMutableString* value = [[NSMutableString alloc] initWithString:self];
		[value insertString:separator atIndex:3];
		[value insertString:separator atIndex:8];
		return value;
	}
	return nil;
}

- (NSString*)formatSecrectPhoneNumberString
{
	if ([self isValidPhoneNumber]) {
		NSMutableString *newStr = [NSMutableString stringWithString:self];
		NSRange range = NSMakeRange(3, 4);
		[newStr replaceCharactersInRange:range withString:@"****"];
		return newStr;
	}
	return nil;
}


@end

@implementation NSString (Valid)

- (BOOL)isValidWithPredicate:(NSString *)predicate {
	NSPredicate *pre = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", predicate];
	return [pre evaluateWithObject:self];
}

- (BOOL)isValidPhoneNumber {
	NSString* const MOBILE = @"\\d{11}$";
	NSPredicate* predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", MOBILE];
	return [predicate evaluateWithObject:self];
}

- (BOOL)isValidEmail
{
	NSString *emailRegex = @"[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}";
	NSPredicate *emailTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", emailRegex];

	return [emailTest evaluateWithObject:self];
}

- (BOOL)isValidIDCardNumber
{
	NSString * value = [self stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
	if ([value length] != 18) {
		return NO;
	}
	NSString *mmdd = @"(((0[13578]|1[02])(0[1-9]|[12][0-9]|3[01]))|((0[469]|11)(0[1-9]|[12][0-9]|30))|(02(0[1-9]|[1][0-9]|2[0-8])))";
	NSString *leapMmdd = @"0229";
	NSString *year = @"(19|20)[0-9]{2}";
	NSString *leapYear = @"(19|20)(0[48]|[2468][048]|[13579][26])";
	NSString *yearMmdd = [NSString stringWithFormat:@"%@%@", year, mmdd];
	NSString *leapyearMmdd = [NSString stringWithFormat:@"%@%@", leapYear, leapMmdd];
	NSString *yyyyMmdd = [NSString stringWithFormat:@"((%@)|(%@)|(%@))", yearMmdd, leapyearMmdd, @"20000229"];
	NSString *area = @"(1[1-5]|2[1-3]|3[1-7]|4[1-6]|5[0-4]|6[1-5]|82|[7-9]1)[0-9]{4}";
	NSString *regex = [NSString stringWithFormat:@"%@%@%@", area, yyyyMmdd  , @"[0-9]{3}[0-9Xx]"];

	NSPredicate *regexTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];
	if (![regexTest evaluateWithObject:value]) {
		return NO;
	}
	int summary = ([value substringWithRange:NSMakeRange(0,1)].intValue + [value substringWithRange:NSMakeRange(10,1)].intValue) *7
	+ ([value substringWithRange:NSMakeRange(1,1)].intValue + [value substringWithRange:NSMakeRange(11,1)].intValue) *9
	+ ([value substringWithRange:NSMakeRange(2,1)].intValue + [value substringWithRange:NSMakeRange(12,1)].intValue) *10
	+ ([value substringWithRange:NSMakeRange(3,1)].intValue + [value substringWithRange:NSMakeRange(13,1)].intValue) *5
	+ ([value substringWithRange:NSMakeRange(4,1)].intValue + [value substringWithRange:NSMakeRange(14,1)].intValue) *8
	+ ([value substringWithRange:NSMakeRange(5,1)].intValue + [value substringWithRange:NSMakeRange(15,1)].intValue) *4
	+ ([value substringWithRange:NSMakeRange(6,1)].intValue + [value substringWithRange:NSMakeRange(16,1)].intValue) *2
	+ [value substringWithRange:NSMakeRange(7,1)].intValue *1 + [value substringWithRange:NSMakeRange(8,1)].intValue *6
	+ [value substringWithRange:NSMakeRange(9,1)].intValue *3;
	NSInteger remainder = summary % 11;
	NSString *checkBit = @"";
	NSString *checkString = @"10X98765432";
	checkBit = [checkString substringWithRange:NSMakeRange(remainder,1)];

	// 判断校验位
	return [checkBit isEqualToString:[[value substringWithRange:NSMakeRange(17,1)] uppercaseString]];
}

- (BOOL)isOnlyNumber;
{
	NSString* number = @"^[0-9]+$";
	NSPredicate *numberPre = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",number];
	return [numberPre evaluateWithObject:self];
}

- (BOOL)isOnlyChinese
{
	NSString * chineseTest=@"^[\u4e00-\u9fa5]{0,}$";
	NSPredicate*chinesePredicate=[NSPredicate predicateWithFormat:@"SELF MATCHES %@",chineseTest];
	return [chinesePredicate evaluateWithObject:self];
}

@end


